//
//  RickyRefreshCoreTextView.m
//  Ricky_RefreshControl
//
//  Created by MR-zhang on 15/7/7.
//  Copyright (c) 2015年 Ricky. All rights reserved.
//

#import "RickyRefreshCoreTextView.h"
#import <CoreText/CoreText.h>

static CGFloat const fontMinSize = 28.0;
static CGFloat const fontMaxSize = 40.0;

//======================NSString(category)==================
@interface NSString (Glyphs)
- (UIBezierPath *)bezierPathWithFont:(UIFont *)font;
@end

@implementation NSString (Glyphs)

- (UIBezierPath *)bezierPathWithFont:(UIFont *)font
{
    CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL);
    NSAttributedString *attributed = [[NSAttributedString alloc] initWithString:self attributes:[NSDictionary dictionaryWithObject:(__bridge id)ctFont forKey:(__bridge NSString *)kCTFontAttributeName]];
    CFRelease(ctFont);
    
    CGMutablePathRef letters = CGPathCreateMutable();
    CTLineRef line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)attributed);
    CFArrayRef runArray = CTLineGetGlyphRuns(line);
    
    for (CFIndex index=0; index<CFArrayGetCount(runArray); index++) {
        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, index);
        CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
        
        for (CFIndex runGlyphIndex=0; runGlyphIndex<CTRunGetGlyphCount(run); runGlyphIndex++) {
            CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
            CGGlyph glyph;
            CGPoint position;
            CTRunGetGlyphs(run, thisGlyphRange, &glyph);
            CTRunGetPositions(run, thisGlyphRange, &position);
            
            CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
            CGAffineTransform transform = CGAffineTransformMakeTranslation(position.x, position.y);
            CGPathAddPath(letters, &transform, letter);
            CGPathRelease(letter);
        }
    }
    
    UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:letters];
    CGRect boundingBox = CGPathGetBoundingBox(letters);
    CGPathRelease(letters);
    CFRelease(line);
    
    // The path is upside down (CG coordinate system)
    [path applyTransform:CGAffineTransformMakeScale(1.0, -1.0)];
    [path applyTransform:CGAffineTransformMakeTranslation(0.0, boundingBox.size.height)];
    return path;
}

@end


//====================RickyRefreshCoreTextView(category)==================
@interface RickyRefreshCoreTextView (ColorImage)

- (UIImage *)imageFromColor:(UIColor *)color contextSize:(CGSize)size;

@end

@implementation RickyRefreshCoreTextView (ColorImage)

- (UIImage *)imageFromColor:(UIColor *)color contextSize:(CGSize)size
{
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

@end

//======================RickyRefreshCoreTextView=====================
@interface RickyRefreshCoreTextView ()
@property (nonatomic, assign, getter=isLoading) BOOL loading;
@property (nonatomic, strong) CAShapeLayer *pullTextLayer;
@property (nonatomic, strong) CATextLayer *refreshTextLayer;
@end

@implementation RickyRefreshCoreTextView

- (id)initWithRefreshViewType:(RickyRefreshViewType)viewType
{
    self = [super initWithRefreshViewType:viewType];
    if (self) {
        self.backgroundColor = [UIColor colorWithWhite:0.98 alpha:0.3];
    }
    return self;
}

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];
    self.loading = NO;
}

// 调整位置
- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    
    if (_pullTextLayer) {
        CGSize textSize = MB_TEXTSIZE(self.pullText, self.pullTextFont);
        [_pullTextLayer setPosition:CGPointMake(screenWidth-textSize.width/2, (self.frame.size.height-textSize.height)/2)];
    }
    
    if (_refreshTextLayer) {
        CGSize textSize = MB_TEXTSIZE(self.refreshingText, self.refreshingTextFont);
        [_refreshTextLayer setPosition:CGPointMake(screenWidth-textSize.width/2, self.frame.size.height-textSize.height/2)];// center text in master layer
    }

}

#pragma mark --
#pragma mark -- 添加文字层
- (CAShapeLayer *)addPullTextLayer
{
    if (!_pullTextLayer) {
        _pullTextLayer = ({
            CAShapeLayer *layer = [CAShapeLayer layer];
            [layer setFrame:self.bounds];
            [layer setPath:[[self.pullText bezierPathWithFont:self.pullTextFont] CGPath]];
            [layer setStrokeColor:self.pullTextColor.CGColor];
            [layer setFillColor:[UIColor colorWithWhite:0.6 alpha:0.1].CGColor];
            [layer setLineWidth:0.5];
            [layer setSpeed:0];
            
            CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
            [textAnimation setFromValue:@0];
            [textAnimation setToValue:@1];
            [textAnimation setDuration:1];
            [textAnimation setRemovedOnCompletion:NO];
            [layer addAnimation:textAnimation forKey:@"textAnimation"];
            layer;
        });
    }
    
    return _pullTextLayer;
}

- (CATextLayer *)addRefreshTextLayer
{
    if (!_refreshTextLayer) {
        _refreshTextLayer = ({
            CATextLayer *layer = [CATextLayer layer];
            [layer setFrame:self.bounds];
            [layer setString:(id)self.refreshingText];
            [layer setFont:CTFontCreateWithName((__bridge CFStringRef)self.refreshingTextFont.fontName, self.refreshingTextFont.pointSize, NULL)];
            [layer setFontSize:self.refreshingTextFont.pointSize];
            [layer setForegroundColor:self.refreshingTextColor.CGColor];
            [layer setContentsScale:[UIScreen mainScreen].scale];
            
            CALayer *maskLayer = [CALayer layer];
            maskLayer.backgroundColor = [UIColor colorWithRed:0.0 green:0.0f blue:0.0f alpha:0.5f].CGColor;
            maskLayer.contents = (id)[self imageFromColor:[UIColor blackColor] contextSize:CGSizeMake(10, 100)].CGImage;
            maskLayer.contentsGravity = kCAGravityCenter;
            maskLayer.frame = CGRectMake(self.frame.size.width * -1, 0.0f, self.frame.size.width*2, self.frame.size.height);
            layer.mask = maskLayer;
            
            CABasicAnimation *maskAnimation = [CABasicAnimation animationWithKeyPath:@"position.x"];
            maskAnimation.byValue = @(self.frame.size.width);
            maskAnimation.repeatCount = INT_MAX;
            maskAnimation.duration = 2.0f;
            [maskLayer addAnimation:maskAnimation forKey:@"slideAnimation"];
            layer;
        });
    }
    
    return _refreshTextLayer;
}

#pragma mark --
#pragma mark -- setter（校正文字大小属性，避免太大，太小的情况）
// PullTextFont
- (void)setPullTextFont:(UIFont *)pullTextFont
{
    UIFont *font = pullTextFont;
    
    if (font.pointSize <= fontMinSize) {// 限定最小值
        font = [UIFont fontWithName:pullTextFont.fontName size:fontMinSize];
    } else if (font.pointSize >= fontMaxSize) {// 限定最大值
        font = [UIFont fontWithName:pullTextFont.fontName size:fontMaxSize];
    }
    _pullTextFont = font;
}

// RefreshingTextFont
- (void)setRefreshingTextFont:(UIFont *)refreshingTextFont
{
    UIFont *font = refreshingTextFont;
    
    if (font.pointSize <= fontMinSize) {// 限定最小值
        font = [UIFont fontWithName:refreshingTextFont.fontName size:fontMinSize];
    } else if (font.pointSize >= fontMaxSize) {// 限定最大值
        font = [UIFont fontWithName:refreshingTextFont.fontName size:fontMaxSize];
    }
    _refreshingTextFont = font;
}

#pragma mark --
#pragma mark -- private method
- (void)startLoading
{
    [self setLoading:YES];
}

- (void)setLoading:(BOOL)loading
{
    _loading = loading;
    
    self.layer.sublayers = nil;
    if (_loading) {
        [self.layer addSublayer:[self addRefreshTextLayer]];
    } else {
        [self.layer addSublayer:[self addPullTextLayer]];
    }
}

#pragma mark -- 
#pragma mark -- 重写父类属性
- (void)setRefreshState:(RickyRefreshState)refreshState
{
    [super setRefreshState:refreshState];
    if (refreshState == RickyRefreshStateRefreshing) {
        [self setLoading:YES];
    }
}

- (void)setRefreshRatio:(CGFloat)refreshRatio
{
    [(CALayer *)[self.layer.sublayers firstObject] setTimeOffset:refreshRatio];
}

- (void)setCompleteType:(RickyRefreshCompleteType)completeType
{
    [super setCompleteType:completeType];

    __weak __typeof(self) weakSelf= self;
    dispatch_async(dispatch_get_main_queue(), ^{
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        __weak __typeof(strongSelf)weakSelf = strongSelf;
        [strongSelf setRefreshState:RickyRefreshStateNormal withCallBack:^{
            __weak __typeof(weakSelf)strongSelf = weakSelf;
            [strongSelf setLoading:NO];
        }];
    });
}

#pragma mark -- 添加从后台返回通知，保证动画正常进行不会停止
- (void)reloadNotification:(NSNotification *)notification
{
    if (self.refreshState == RickyRefreshStateRefreshing) {
        self.refreshTextLayer = nil;
        [self startLoading];
    }
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
